package cn.school.course.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.school.common.exception.ApiException;
import cn.school.common.utils.CourseUtils;
import cn.school.common.utils.WeekDayVo;
import cn.school.course.dao.CourseDao;
import cn.school.course.dao.CourseSessionsDao;
import cn.school.course.entity.Course;
import cn.school.course.entity.CourseConflict;
import cn.school.course.entity.CoursePlanConflict;
import cn.school.course.entity.CourseSessions;
import cn.school.course.service.CourseConflictService;
import cn.school.course.service.CoursePlanConflictService;
import cn.school.course.service.CourseService;
import cn.school.course.vo.WeekCourseTableBySchoolClassReqVo;
import cn.school.course.vo.WeekCourseTableBySchoolClassRspVo;
import cn.school.sys.entity.TermTime;
import cn.school.sys.service.TermTimeService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * @className: 课程ServiceImpl
 * @author: fangjin.tao
 * @date: 2023/1/4
 **/
@Service
public class CourseServiceImpl extends ServiceImpl<CourseDao, Course> implements CourseService {
	@Autowired
	private CourseConflictService courseConflictService;
	@Autowired
	private TermTimeService termTimeService;
	@Autowired
	private CourseSessionsDao courseSessionsDao;
	@Autowired
	private CoursePlanConflictService coursePlanConflictService;
	
	@Override
	public WeekCourseTableBySchoolClassRspVo getClassCourseTable(List<CourseSessions> courseSessionsList, WeekCourseTableBySchoolClassReqVo reqVo) {
		List<Course> courseList = this.baseMapper.selectCourseByWeekTable(reqVo);
		WeekCourseTableBySchoolClassRspVo rspVo = new WeekCourseTableBySchoolClassRspVo(reqVo, courseSessionsList, courseList);
		rspVo.setScclId(reqVo.getScclId().toString());
		return rspVo;
	}
	
	@Override
	public IPage<Course> pageByCourseList(IPage<Course> page, QueryWrapper<Course> queryWrapper) {
		List<Course> list = this.baseMapper.selectCourse(page, queryWrapper);
		page.setRecords(list);
		return page;
	}
	
	@Override
	@Transactional
	public void saveOrUpdateMyDefined(Course course) {
		TermTime termTime = this.termTimeService.getTermTimeById(course.getTetiId());
		List<String> allTeacherKeyeyList = new ArrayList<>();
		List<String> allRommKeyList = new ArrayList<>();
		
		if (termTime == null) {
			throw new ApiException("对应的学年学期不存在，请刷新界面再试");
		}
		CourseConflict courseConflict = null;
		CoursePlanConflict coursePlanConflict = null;
		CourseSessions courseSessions = this.courseSessionsDao.selectById(course.getCoseId());
		WeekDayVo weekDayVo = CourseUtils.gennerWeedDayDate(termTime.getTetiTermBeginDate(), course.getCoplWeekNo(), course.getCoplWeekDayNo());
		course.setCourBeginTime(DateUtil.parse(DateUtil.format(weekDayVo.getDate(), "yyyy-MM-dd") + " " + courseSessions.getCoseBeginTime(), "yyyy-MM-dd HH:mm:ss"));
		course.setCourEndTime(DateUtil.parse(DateUtil.format(weekDayVo.getDate(), "yyyy-MM-dd") + " " + courseSessions.getCoseEndTime(), "yyyy-MM-dd HH:mm:ss"));
		if (course.getId() == null) {
			courseConflict = new CourseConflict();
			
			coursePlanConflict = new CoursePlanConflict();
			BeanUtil.copyProperties(course, coursePlanConflict);
			coursePlanConflict.setCpcoTeacherKey("");
			courseConflict.setCpcoTeacherKey(course.getTetiId() + "_" + course.getSyusId() + "_"
					+ course.getCoplWeekNo() + "_" + course.getCoseId() + "_" + course.getCoplWeekDayNo());
			coursePlanConflict.setCpcoRoomKey(course.getTetiId() + "_" + course.getBsloId() + "_"
					+ course.getCoplWeekNo() + "_" + course.getCoseId() + "_" + course.getCoplWeekDayNo());
			coursePlanConflict.setCpcoIsGennerCourse(1);
			this.coursePlanConflictService.save(coursePlanConflict);
			
			BeanUtil.copyProperties(course, courseConflict);
			courseConflict.setCpcoTeacherKey("");
			courseConflict.setCpcoTeacherKey(course.getTetiId() + "_" + course.getSyusId() + "_"
					+ course.getCoplWeekNo() + "_" + course.getCoseId() + "_" + course.getCoplWeekDayNo());
			courseConflict.setCpcoRoomKey(course.getTetiId() + "_" + course.getBsloId() + "_"
					+ course.getCoplWeekNo() + "_" + course.getCoseId() + "_" + course.getCoplWeekDayNo());
			courseConflict.setCpcoId(coursePlanConflict.getId());
			courseConflict.setCpcoIsGennerCourse(1);
			this.courseConflictService.save(courseConflict);
			
			course.setCpcoId(coursePlanConflict.getId());
			course.setCocoId(courseConflict.getId());
			course.setTetiId(course.getTetiId());
			this.save(course);
			allTeacherKeyeyList.add(courseConflict.getCpcoTeacherKey());
			allRommKeyList.add(courseConflict.getCpcoRoomKey());
		} else {
			Course oldCourse = this.baseMapper.selectById(course.getId());
			courseConflict = this.courseConflictService.getById(oldCourse.getCocoId());
			String cpcoRoomKeyByOLd = courseConflict.getCpcoRoomKey();
			String cpcoTeacherKeyByOld = courseConflict.getCpcoTeacherKey();
			BeanUtil.copyProperties(course, courseConflict);
			courseConflict.setId(oldCourse.getCocoId());
			courseConflict.setCpcoTeacherKey(course.getTetiId() + "_" + course.getSyusId() + "_"
					+ course.getCoplWeekNo() + "_" + course.getCoseId() + "_" + course.getCoplWeekDayNo());
			courseConflict.setCpcoRoomKey(course.getTetiId() + "_" + course.getBsloId() + "_"
					+ course.getCoplWeekNo() + "_" + course.getCoseId() + "_" + course.getCoplWeekDayNo());
			courseConflict.setCpcoIsConflict(0);
			courseConflict.setCpcoIsChanged(1);
			courseConflict.setCpcoConflictType("");
			courseConflict.setCpcoId(oldCourse.getCpcoId());
			this.courseConflictService.updateById(courseConflict);
			
			coursePlanConflict = this.coursePlanConflictService.getById(oldCourse.getCpcoId());
			BeanUtil.copyProperties(course, coursePlanConflict);
			coursePlanConflict.setId(oldCourse.getCpcoId());
			coursePlanConflict.setCpcoTeacherKey(courseConflict.getCpcoTeacherKey());
			coursePlanConflict.setCpcoRoomKey(courseConflict.getCpcoRoomKey());
			coursePlanConflict.setCpcoIsConflict(0);
			coursePlanConflict.setCpcoIsChanged(1);
			coursePlanConflict.setCpcoConflictType("");
			this.coursePlanConflictService.updateById(coursePlanConflict);
			course.setCpcoId(oldCourse.getCpcoId());
			course.setCocoId(oldCourse.getCocoId());
			course.setModifyTime(Calendar.getInstance().getTime());
			this.saveOrUpdate(course);
			
			allTeacherKeyeyList.add(courseConflict.getCpcoTeacherKey());
			if (!courseConflict.getCpcoTeacherKey().equals(cpcoTeacherKeyByOld)) {
				allTeacherKeyeyList.add(cpcoTeacherKeyByOld);
			}
			allRommKeyList.add(courseConflict.getCpcoRoomKey());
			if (!courseConflict.getCpcoRoomKey().equals(cpcoRoomKeyByOLd)) {
				allRommKeyList.add(cpcoRoomKeyByOLd);
			}
			
		}
		
		// 更新冲突情况
		this.courseConflictService.updateConflictCase(termTime, allTeacherKeyeyList, allRommKeyList);
	}
	
	@Override
	@Transactional
	public void deleteCourse(Long courId) {
		Course course = this.getById(courId);
		if (course == null) {
			return;
		}
		TermTime termTime = this.termTimeService.getTermTimeById(course.getTetiId());
		// 课程超过当前时间
		Boolean courseTimeIsValid = false;
		if (course.getCourEndTime().getTime() >= Calendar.getInstance().getTime().getTime()) {
			courseTimeIsValid = true;
		}
		
		if (courseTimeIsValid) {
			// 删除排课计划冲突
			CoursePlanConflict coursePlanConflict = this.coursePlanConflictService.getById(course.getCpcoId());
			this.coursePlanConflictService.removeById(course.getCpcoId());
			
			// 删除课表冲突
			CourseConflict courseConflict = this.courseConflictService.getById(course.getCocoId());
			this.courseConflictService.removeById(course.getCocoId());
			// 更新课表冲突
			List<String> allTeacherKeyList = new ArrayList<>();
			List<String> allRommKeyList = new ArrayList<>();
			allTeacherKeyList.add(coursePlanConflict.getCpcoTeacherKey());
			allRommKeyList.add(coursePlanConflict.getCpcoRoomKey());
			this.courseConflictService.updateConflictCase(termTime, allTeacherKeyList, allRommKeyList);
		}
		// 删除课程
		this.baseMapper.deleteById(course.getId());
	}
}
